package com.it.gmall.order.listener;

import com.it.gmall.model.enums.OrderStatus;
import com.it.gmall.model.enums.ProcessStatus;
import com.it.gmall.model.order.OrderInfo;
import com.it.gmall.mq.consts.MqConst;
import com.it.gmall.mq.service.SendMsgService;
import com.it.gmall.order.mapper.OrderApiMapper;
import com.it.gmall.order.service.OrderApiService;
import com.it.gmall.payment.client.PaymentFeignClient;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;

@Component
public class OrderInfoListener {
    @Autowired
    private OrderApiMapper orderApiMapper;
    @Autowired
    private OrderApiService orderApiService;
    @Autowired
    private SendMsgService sendMsgService;
    @Autowired
    private PaymentFeignClient paymentFeignClient;

    // 接收取消订单的延迟消息
    @RabbitListener(queues = {MqConst.QUEUE_ORDER_CANCEL})
    public void listenerCancelOrder(long orderId, Message message, Channel channel){
        try {
            System.out.println("接收到取消订单的时间是:"+new Date());
            OrderInfo orderInfo = orderApiService.getOrderInfo(orderId);
            // 只有是未支付的状态才修改为取消 其余不取消
            if(OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus())){
                // 关闭支付宝交易接口
                String closeResult = paymentFeignClient.alipayTradeClose(orderId);
                if("success".equals(closeResult)){ // 只有在支付宝接口关闭以后 才可以取消订单
                    // 修改订单状态和进度状态
                    orderApiService.updateOrderInfoStatus(orderId,ProcessStatus.CLOSED);
                }
            }
            // 手动应答消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 支付成功之后-支付微服务通知订单微服务修改订单得状态
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_PAYMENT_PAY),
            value = @Queue(value = MqConst.QUEUE_PAYMENT_PAY,durable = "true",autoDelete = "false"),
            key = {MqConst.ROUTING_PAYMENT_PAY}
    ))
    public void updateOrderInfoStatus(Long orderId,Message message,Channel channel){
        System.out.println("订单微服务接收到的订单id是："+orderId);
        try {
            if(null!=orderId){ // 判断非空
                OrderInfo orderInfo = orderApiService.getOrderInfo(orderId);
                // 做幂等判断 防止订单的重复提交
                if(orderInfo!=null && OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus())){
                    // 更改订单状态和支付的状态
                    orderApiService.updateOrderInfoStatus(orderId,ProcessStatus.PAID);
                    // 封装返回给库存的对象
                    String result = orderApiService.initWareInfo(orderId);
                    // 通知库存微服务 进行 扣减库存
                    sendMsgService.sendMsg(MqConst.EXCHANGE_DIRECT_WARE_STOCK,MqConst.ROUTING_WARE_STOCK,result);
                }
            }
            // 手动应答消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 库存减库存之后-拆单结果
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_WARE_ORDER),
            value = @Queue(value = MqConst.QUEUE_WARE_ORDER,durable = "true",autoDelete = "false"),
            key = {MqConst.ROUTING_WARE_ORDER}
    ))
    public void updateLockStockStatus(String result,Message message,Channel channel){
        System.out.println("减库存的结果是："+result);
        try {
            orderApiService.updateLockStockStatus(result);
            // 手动应答消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
